import Scenes from "./Scenes"
import Rigidbody from '../Physics/Rigidbody'
import Vector2 from "../Base/Vector2";
import BaseManager from '../Manager/Index'
import Stage from "./Stage";
let uid = 0;

enum SpriteType {
    Text = 'text',
    ImageBitmap = 'bitmap'
}

export enum SpriteTextType {
    Fill = 'fill',
    Stroke = 'stroke'
}

class Sprite extends Rigidbody {
    parent: Stage;
    id: number;
    _sprite: {
        source: CanvasImageSource | string,
        width: number,
        height: number,
        style?: string,
        mode?: SpriteTextType
    };
    canvas: HTMLCanvasElement;
    ctx: CanvasRenderingContext2D;
    type: SpriteType;
    private script: Array<any>;
    constructor(x, y, width, height, parent: Stage, script?: any) {
        const options = {
            gravity: 0,
            mass: 0,
            acceleration: new Vector2(0, 0),
            resistince: 0,
            velocity: new Vector2(0, 0),
            position: new Vector2(x, y),
        }
        super(options);
        this.id = uid++;
        this.parent = parent;
        this.script = [script];
        if (this.parent) this.parent.addChild(this)
        this.canvas = document.createElement('canvas');
        this.canvas.width = width;
        this.canvas.height = height;
        this.ctx = this.canvas.getContext('2d');
        const leftCycle = {
            start: [this.start.bind(this)],
            update: [this.update.bind(this)]
        }

        if (this.script && Array.isArray(this.script)) {


            this.script.forEach(CustomClass => {
                const customClass = new CustomClass(this);

                leftCycle.start.push(customClass.start.bind(customClass))
                leftCycle.update.push(customClass.update.bind(customClass))
            })
        }

        BaseManager.addSpriteLifeCycle(this.id, leftCycle);
    }
    start() {
        console.log('Sprite Start!!!');
    }
    setCharacterSprite(source, width, height) {
        this._sprite = {
            source, width, height
        }
        this.type = SpriteType.ImageBitmap;
    }

    setTextSprite(source, width, height, mode?: SpriteTextType, style?: string) {
        this._sprite = {
            source, width, height, mode: mode || SpriteTextType.Stroke, style
        }
        this.type = SpriteType.Text;
    }

    getPos() {
        return this.position
    }

    update() {
        this.parent.graphics._clearRect(this.position.x, this.position.y, this.canvas.width, this.canvas.height);
        this.move()
        this.render()
    }

    render() {

        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        if (this.type === SpriteType.ImageBitmap) {
            this.ctx.drawImage(this._sprite.source as CanvasImageSource, this.position.x, this.position.y, this._sprite.width, this._sprite.height)
        } else if (this.type === SpriteType.Text) {

            if (this._sprite.mode === SpriteTextType.Stroke) {
                this.ctx.strokeStyle = 'red';
                this.ctx.font = "40pt Calibri";
                this.ctx.strokeText(this._sprite.source as string, 30, 30)
            } else {
                this.ctx.font = "40pt Calibri";
                this.ctx.fillStyle = 'red';
                this.ctx.fillText(this._sprite.source as string, 0, 30)
            }
        } else {
            throw new Error('the Sprite source is not exist!')
        }
        this.parent.graphics.drawImage(this.canvas, this.position.x, this.position.y, this.canvas.width, this.canvas.height);
    }
}



export default Sprite